package generic;

import java.util.ArrayList;
/**
 * 泛型限定:
 *   需求:
 *     1.定义三个类 父类:人类 两个子类: 学生类 老师类
 *       他们有一个通用的方法吃方法
 *     2.定义三个集合,这三个集合分别存储人对象,学生对象,老师对象
 *     3.定义一个方法,该方法可以接收以上的三个集合,同时再该方法中遍历接收到集合,调用吃方法
 *   ? extends E : 泛型上限 作用:限制传入的泛型只能为E类型或E的子类型
 *                 优点:可以限定到一个类的体系,一定程度避免强转的麻烦
 *   ? super E : 泛型下限 作用: 限制传入的泛型只能为E类型或E的父类型
 */
public class GenericDemo02 {
    public static void main(String[] args) {
        //创建一个存储Person的集合
        ArrayList<Person> people = new ArrayList<>();
        people.add(new Person("小张"));
        people.add(new Person("小王"));

        //创建一个存储Student的集合
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("老王"));
        students.add(new Student("老张"));

        //创建一个存储Teacher的集合
        ArrayList<Teacher> teachers = new ArrayList<>();
        teachers.add(new Teacher("张三"));
        teachers.add(new Teacher("李四"));

        method(people);
        System.out.println("==================");
        method(students);
        System.out.println("==================");
        method(teachers);

        //ArrayList<Integer> al = new ArrayList<>(Arrays.asList(3, 5, 7));
        //method(al);
    }


  /*  public static void method(ArrayList<?> al) {
        for (Object obj : al){ //例如: 传入的是ArrayList<Person> : Object obj = new Person(); //多态
                               // 传入的是 ArrayList<Student>  : Object obj = new Student();
                              //传入的是  ArrayList<Teacher> : Object obj = new Teacher();
                               //传入的是 ArrayList<Integer>: Object obj = new Integer();
             //无论是强转成学生或者强转成老师,都无法兼容传过来的三种集合
            //Student stu = (Student)obj;
            //stu.eat();
            //Teacher t = (Teacher) obj;
            //t.eat();
            Person p = (Person) obj;
            p.eat();
        }
}
   */

    /**
     *
     * @param al ArrayList<? extends Person>:限定将来传入的集合的泛型是 Person类型或者是 Person的子类型
     *           传入的集合使用的泛型是Person体系的类
     */
    public static void method(ArrayList<? extends Person> al){
        //ArrayList<? extends Person>:代表集合中存储的元素的类型有两大类: 要么是Person类型, 要么是Person的子类型
            for(Person p:al){ //例如: 传入的是ArrayList<Person> :Person p = new Person();
                              // 传入的是 ArrayList<Student>  :Person p = new Student(); 多态
                              //传入的是  ArrayList<Teacher> : Person p = new Teacher(); 多态
                              //传入的是 ArrayList<Integer>: Person p = new Integer(); //无法兼容,也无法传入
            p.eat();
        }
    }

}
